package com.leon.collection;

public class LeonLinkedList<T> {

    private int size;

    private Node<T> first;

    private Node<T> end;

    public void add(T t) {
        final Node<T> l = end;
        final Node<T> f = first;
        Node<T> newNode = new Node<>(l, t, null);
        if (null != end) {
            l.next = newNode;
        } else {
            first = newNode;
        }
        end = newNode;
        size++;
    }

    public T get(int index) {
        if (index < 0) {
            throw new IllegalArgumentException();
        }
        if (index > size) {
            throw new IndexOutOfBoundsException();
        }
        if (index == 0) {
            return first.item;
        }
        if (index == size - 1) {
            return end.item;
        }
        if (index < (size >> 1)) {
            Node<T> currentNode = first;
            for (int i = 0; i < size; i++) {
                currentNode = currentNode.next;
            }
            return currentNode.item;
        } else {
            Node<T> currentNode = end;
            for (int i = 0; i < size; i++) {
                currentNode = currentNode.pre;
            }
            return currentNode.item;
        }
    }

    public T poll() {
        final T element = first.item;
        final Node<T> f = first;
        final Node<T> next = first.next;

        /**
         * help gc
         */
        f.item = null;
        f.next = null;


        first = next;
        end.pre = null;
        size--;
        return element;
    }

    public T offer(T t) {
        final Node<T> last = end;
        Node<T> newNode = new Node<>(last, t, null);
        if (last == null) {
            first = newNode;
        } else {
            end = newNode;
        }
        size++;
    }

    private static class Node<E> {
        private E item;
        private Node<E> pre;
        private Node<E> next;

        public Node(Node<E> pre, E item, Node<E> next) {
            this.item = item;
            this.pre = pre;
            this.next = next;
        }
    }

}
